package com.ruoyi.partybuilding.controller;

import cn.hutool.core.date.DateUtil;
import cn.hutool.json.JSONUtil;
import com.ruoyi.common.core.domain.entity.SysDept;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.partybuilding.domain.*;
import com.ruoyi.partybuilding.domain.vo.DeptOrgVo;
import com.ruoyi.partybuilding.domain.vo.MeetingInfoVo;
import com.ruoyi.partybuilding.domain.vo.MeetingStatVo;
import com.ruoyi.partybuilding.service.impl.MeetingInfoServiceImpl;
import com.ruoyi.partybuilding.service.impl.MessageServiceImpl;
import com.ruoyi.partybuilding.service.impl.OrgServiceImpl;
import com.ruoyi.system.service.ISysDictTypeService;
import io.swagger.annotations.*;
import org.apache.commons.lang3.time.DateUtils;
import org.springframework.data.domain.*;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import org.springframework.security.access.prepost.PreAuthorize;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.util.*;
import java.util.stream.Collectors;

import lombok.var;
import com.ruoyi.common.core.domain.*;
import com.ruoyi.common.core.page.*;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.constant.HttpStatus;
import com.ruoyi.common.enums.BusinessType;
//import com.ruoyi.partybuilding.service.MeetingInfoService;
import com.ruoyi.partybuilding.common.*;
import reactor.util.function.Tuple3;
import reactor.util.function.Tuples;

/**meeting_info
 * 会议信息;(pb_meeting_info)表控制层
 * @author : He-LiangLiang@Outlook.com
 * @date : 2024-12-5
 */
@Api(tags = "会议信息对象功能接口")
@RestController
@RequestMapping("/partybuilding/MeetingInfo")
public class MeetingInfoController extends EQueryController<MeetingInfo>{

    @ApiOperation(value = "会议统计",notes = "t1每月会议统计;t2线下会议统计;t3在线会议统计")
    //@PreAuthorize("@ss.hasPermi('partybuilding:MeetingInfo:MeetingStat')")
    @GetMapping("meetingStat")
    public R<Tuple3<List<MeetingStatVo>, List<MeetingStatVo>, List<MeetingStatVo>>> meetingStat(Long deptId,Integer year) {
        if (year == null || deptId == null)
            return R.fail("参数错误");
        var list = meetingInfoService.MeetingStat(deptId, year, null);
        var online0 = meetingInfoService.MeetingStat(deptId, year, 0l);
        var online1 = meetingInfoService.MeetingStat(deptId, year, 1l);
        var typeList = dictTypeService.selectDictDataByType("pb_meeting_type");
        DataUtil.findSet(list, typeList, (p, p1) -> Objects.equals(p.getTypeCode(), p1.getDictValue()),
                (p, p1) -> {
                    p.setTypeName(p1.getDictLabel());
                });
        DataUtil.findSet(online0, typeList, (p, p1) -> Objects.equals(p.getTypeCode(), p1.getDictValue()),
                (p, p1) -> {
                    p.setTypeName(p1.getDictLabel());
                });
        DataUtil.findSet(online1, typeList, (p, p1) -> Objects.equals(p.getTypeCode(), p1.getDictValue()),
                (p, p1) -> {
                    p.setTypeName(p1.getDictLabel());
                });

        R<Tuple3<List<MeetingStatVo>, List<MeetingStatVo>, List<MeetingStatVo>>> ok = R.ok(Tuples.of(list, online0, online1));
        return ok;
    }
    @ApiOperation("会议详情，会返回人员列表详情")
    @PreAuthorize("@ss.hasPermi('partybuilding:MeetingInfo:query')")
    @GetMapping(value = "/{id}")
    public R<MeetingInfo> getInfo(@PathVariable("id") Long id) {
        var re = super.getInfo(id);
        var ids = JSONUtil.toList(re.getData().getUsers(), Long.class);
        var userList = queryHelper.queryable(SysUserRef.class).where(p -> p.in(SysUserRef::getUserId, ids)).toList();
        re.getData().setUserList(userList);
        return re;
    }
    @ApiOperation("分页")
    @PreAuthorize("@ss.hasPermi('partybuilding:MeetingInfo:list')")
    @GetMapping("query")
    public R<Page<MeetingInfo>> query(MeetingInfoVo whereObj, PageDomain pageRequest) {

        return super.queryPage(whereObj, pageRequest);
    }

    @ApiOperation("列表,对query的rouyi兼容包装")
    @PreAuthorize("@ss.hasPermi('partybuilding:MeetingInfo:list')")
    @GetMapping("list")
    public TableDataInfo list(MeetingInfo entity, PageDomain pageRequest) {
        var page= super.queryPage(entity, pageRequest);
        TableDataInfo rspData = new TableDataInfo();
        rspData.setCode(HttpStatus.SUCCESS);
        rspData.setMsg("查询成功");
        rspData.setRows(page.getData().getContent());
        rspData.setTotal(page.getData().getTotalElements());
        return rspData;
    }
    @ApiOperation("会议签到")
    @PostMapping("scanSign/{meetingId}")
    R<String> scanSign(@PathVariable("meetingId") Long meetingId) {
        //var sourTypes=new String[]{"scan","admin","self" };
        var meeting = super.getInfo(meetingId).getData();
        if (meeting == null || meeting.getSignBegin() == null)
            return R.fail("会议无效或未开启签到");
        var signEndTime = meeting.getSignDelay() > -10000 ? DateUtils.addMinutes(meeting.getStartTime(), meeting.getSignDelay()) : DateUtils.addMinutes(meeting.getStartTime(), meeting.getDurtion().intValue());
        if (signEndTime.compareTo(new Date()) > 0)
            return R.fail("签到时间已过");
        //
        var isSigned = queryHelper.queryable(MeetingReceipt.class).where(p -> p.eq(MeetingReceipt::getMeetingId, meetingId).eq(MeetingReceipt::getUserId, getUserId()))
                .any();
        if (isSigned)
            return R.fail("请勿重复签到");
        var mr = createMeetingReceipt(meetingId, "scan",getUserId(),getLoginUser().getUser().getNickName(),getDeptId(),null);
        queryHelper.query().insertable(mr).executeRows();
        return R.ok(mr.getUserName(), "签到成功");
    }


    private MeetingReceipt createMeetingReceipt(Long meetingId, String scan,Long userId,String userName,Long deptId,String deptName) {
        var mr = new MeetingReceipt();
        mr.setMeetingId(meetingId);
        mr.setType(0L);
        mr.setUserId(userId);
        mr.setUserName(userName);
        mr.setDeptId(deptId);
        mr.setDeptName(deptName);
        mr.setSourceSign(scan);
        mr.setState(1l);
        mr.setCreateBy(getUsername());
        mr.setCreateTime(new Date());
        return mr;
    }

    @ApiOperation("会议签到管理员代签")
    @PostMapping("admSign/{meetingId}")
    R<String> admSign(@PathVariable("meetingId") Long meetingId,Long userId) {

        var meeting = super.getInfo(meetingId).getData();
        if (meeting == null )
            return R.fail("会议无效");
        var isSigned = queryHelper.queryable(MeetingReceipt.class).where(p -> p.eq(MeetingReceipt::getMeetingId, meetingId).eq(MeetingReceipt::getUserId, userId))
                .any();
        if (isSigned)
            return R.fail("请勿重复签到");
        var user=queryHelper.queryable(UserMemberDeptV.class).where(p->p.eq(UserMemberDeptV::getUserId,userId)).firstOrNull();
        if(user==null)
            return  R.fail("用户错误的");
        var mr = createMeetingReceipt(meetingId, "adm",userId,user.getNickName(),user.getDeptId(),user.getDeptName());
        queryHelper.query().insertable(mr).executeRows();
        return R.ok(mr.getUserName(), "签到成功");
    }
    @ApiOperation(value = "开启签到",notes ="signDelay签到延迟时间-字典pb_meeting_sign_delay值" )
    @Log(title = "会议信息", businessType = BusinessType.UPDATE)
    @PostMapping("meetingSignBegin")
   public R meetingSignBegin(Long meetingId,Integer signDelay) {
        var meeting = super.getInfo(meetingId).getData();
        meeting.setSignBegin(new Date());
        meeting.setSignDelay(signDelay);
        super.edit(meeting);
        return R.ok("签到已开启");
    }

    @Resource
    OrgServiceImpl orgService;
    @ApiOperation("新增")
    @PreAuthorize("@ss.hasPermi('partybuilding:MeetingInfo:add')")
    @Log(title = "会议信息", businessType = BusinessType.INSERT)
    @PostMapping("add")
    @Transactional
    public R<Long> add(@RequestBody MeetingInfo entity) {
        if (StringUtils.isBlank(entity.getUsers()) || !entity.getUsers().startsWith("["))
            return R.fail("参会人错误");
        entity.setCreatorId(getUserId());
        entity.setCreateBy(getUsername());
        entity.setCreateTime(new Date());
        entity.setStatus(0l);
        if (entity.getDeptId() == null)
            return R.fail("部门信息错误");
        var dept = queryHelper.queryable(SysDept.class).whereById(entity.getDeptId()).firstOrNull();
        if (dept == null)
            return R.fail("部门信息错误");
        entity.setDeptName(dept.getDeptName());
        meetingStatusSet(entity);
        var re = super.add(entity);
        sendMsg(entity);
        return re;
    }
    public void meetingStatusSet(MeetingInfo meeting){
         if(meeting.getStatus()==2)
             return;
         if(meeting.getStartTime().compareTo(new Date())>0)
             meeting.setStatus(0l);
        if(com.ruoyi.common.utils.DateUtils.addMinutes(meeting.getStartTime(),meeting.getDurtion().intValue()).compareTo(new Date())<0)
            meeting.setStatus(2l);
        else
            meeting.setStatus(1l);
    }
    @Resource
    MessageServiceImpl messageService;
    private void sendMsg(MeetingInfo meeting) {
        if (StringUtils.isBlank(meeting.getUsers()) || !meeting.getUsers().startsWith("["))
            return;
        var list = JSONUtil.parseArray(meeting.getUsers()).toList(Long.class).stream().distinct().collect(Collectors.toList());
        var msgList = new ArrayList<Message>();
        list.forEach(p -> {
            var msg = new Message();
            msg.setUserId(p);
            // msg.setUserName(p);
            msg.setTitle("会议提醒：" + meeting.getTitle());
            msg.setContent("会议通知：" + meeting.getTitle()+",开始时间："+ DateUtil.formatDateTime(meeting.getStartTime()));
            msg.setSourceId(meeting.getId() + "");
            msg.setSourceName("sys.meeting.add");
            msg.setCreateBy(getUsername());
            msg.setStatus(0l);
            msg.setCreateTime(new Date());
            msg.setType(0l);
            msgList.add(msg);
        });
        messageService.sendMsg(msgList);
    }
    @ApiOperation("删除")
    @PreAuthorize("@ss.hasPermi('partybuilding:MeetingInfo:remove')")
    @Log(title = "会议信息", businessType = BusinessType.DELETE)
    @PostMapping("remove/{ids}")
    public R<Long> remove(@PathVariable("ids") Long[] ids){
        return super.remove(Arrays.stream(ids).toArray());
    }
    @ApiOperation("编辑")
    @PreAuthorize("@ss.hasPermi('partybuilding:MeetingInfo:edit')")
    @Log(title = "会议信息", businessType = BusinessType.UPDATE)
    @PostMapping("edit")
    public  R<Long> edit(@RequestBody MeetingInfo entity){
        return super.edit(entity);
    }

    @ApiOperation("设置纪要")
    @PreAuthorize("@ss.hasPermi('partybuilding:MeetingInfo:edit')")
    @Log(title = "会议信息", businessType = BusinessType.UPDATE)
    @PostMapping("editRecord")
    public R editRecord(@RequestBody MeetingInfo entity){
        var meeting= getInfo(entity.getId()).getData();
        meeting.setRecord(entity.getRecord());
        return R.ok();
    }
    @ApiOperation("导出")
    @PreAuthorize("@ss.hasPermi('partybuilding:MeetingInfo:export')")
    @Log(title = "会议信息", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    public void export(MeetingInfo entity, PageDomain pageRequest,HttpServletResponse response)
    {
        super.export(entity,pageRequest,null,response);
    }

    @Resource
    MeetingInfoServiceImpl meetingInfoService;

    @Resource
    ISysDictTypeService dictTypeService;

}